package com.book.common.util;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.TimeZone;

/**
 * Description： 常量命名规范 ,YYYY：年；MM：月；DD：日；HH：时；MM：分；SS：秒；L代表前面用线分开，C代表后面用冒号分开
 * @Author： leo.xiong
 * @CreateDate： 2019/8/13 17:12
 * @Email： leo.xiong@suyun360.com
 * Version：1.0
 */
public class DatetimeUtil extends LocalDateUtil {

    public static final Map<Integer, String> PATTERN_MAP = new HashMap() {
        {
            put(4, YYYY);
            put(6, YYYY_MM);
            put(8, YYYY_MM_DD);
            put(10, YYYY_MM_DD_L);
            put(13, YYYY_MM_DD_HH_L);
            put(16, YYYY_MM_DD_HH_MM_L_C);
            put(19, YYYY_MM_DD_HH_MM_SS_L_C);
        }
    };

    public DatetimeUtil() {
    }

    /**
     * 取得当前时间，返回Timestamp对象
     *
     * @param
     * @return Timestamp。
     */
    public static Timestamp getTimestamp(Date date) {
        if (date == null) {
            return null;
        }
        return new Timestamp(date.getTime());
    }

    /**
     * 取得当前时间，返回Timestamp对象
     *
     * @param
     * @return Timestamp。
     */
    public static Timestamp getNow() {
        return new Timestamp(System.currentTimeMillis());
    }

    /**
     * 根据给定格式，返回字符串格式的当前时间
     *
     * @param pattern 给定格式，若给定格式为空，则格式默认为"yyyy-MM-dd HH:mm:ss"
     * @return String。
     */
    public static String getNow(String pattern) {
        return getNow(new Date(), pattern);
    }

    public static String getNow(Date date, String pattern) {
        if (StringUtils.isEmpty(pattern)) {
            pattern = YYYY_MM_DD_HH_MM_SS_L_C;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        String dateStr = sdf.format(date);
        return dateStr;
    }

    public static String getYesterday(String pattern) {
        return getYesterday(new Date(), pattern);
    }

    public static String getYesterday(Date date, String pattern) {
        if (StringUtils.isEmpty(pattern)) {
            pattern = YYYY_MM_DD_HH_MM_SS_L_C;
        }
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(Calendar.DAY_OF_MONTH, -1); //天减1
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        String dateStr = sdf.format(ca.getTime());
        return dateStr;
    }

    /**
     * 获取当天开始时间
     *
     * @return
     */
    public static String getNowStartTime() {
        return getNowStartTime(new Date());
    }

    /**
     * 获取某天的初始时间
     *
     * @param date
     * @return
     */
    public static String getNowStartTime(Date date) {
        return formatDate(date, YYYY_MM_DD_L) + " 00:00:00";
    }

    /**
     * 获取某毫秒的当天初始时间
     *
     * @param time
     * @return
     */
    public static String getNowStartTime(Long time) {
        return formatDate(new Date(time), YYYY_MM_DD_L) + " 00:00:00";
    }

    /**
     * 获取当天前一天开始时间
     *
     * @return
     */
    public static String getYesterdayStartTime() {
        return getYesterdayStartTime(new Date());
    }

    /**
     * 获取某天前一天开始时间
     *
     * @return
     */
    public static String getYesterdayStartTime(Date date) {
        return getYesterday(date, DatetimeUtil.YYYY_MM_DD_L) + " 00:00:00";
    }

    public static String getYesterdayStartTime(Long time) {
        return getYesterdayStartTime(new Date(time));
    }

    /**
     * 获取当天结束时间
     *
     * @return
     */
    public static String getNowEndTime() {
        return getNowEndTime(new Date());
    }

    /**
     * 获取当某天结束时间
     *
     * @return
     */
    public static String getNowEndTime(Date date) {
        return formatDate(date, YYYY_MM_DD_L) + " 23:59:59";
    }

    public static String getNowEndTime(Long time) {
        return formatDate(new Date(time), YYYY_MM_DD_L) + " 23:59:59";
    }

    /**
     * 获取当天前一天开始时间
     *
     * @return
     */
    public static String getYesterdayEndTime() {
        return getYesterdayEndTime(new Date());
    }

    /**
     * 获取某天前一天开始时间
     *
     * @return
     */
    public static String getYesterdayEndTime(Date date) {
        return getYesterday(date, DatetimeUtil.YYYY_MM_DD_L) + " 23:59:59";
    }

    public static String getYesterdayEndTime(Long time) {
        return getYesterdayEndTime(new Date(time));
    }

    /**
     * 截取日期部分
     * <p>
     * 如sDate为null,则返回当前日期
     *
     * @param sDate
     * @return
     */
    public static Date getDate(Date sDate) {
        Date tDate = sDate == null ? new Date() : sDate;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(tDate);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 取得某月天数
     *
     * @param year  int 年（例2004）
     * @param month int 月（1-12）
     * @return int 当月天数
     */
    public static int getDaysOfMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        return calendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 取给定日期前一天
     *
     * @param dateStr String 给定日期(例2004-03-01)
     * @return String
     */
    public static String getPreDay(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(sdf.parse(dateStr));
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 1);
            return sdf.format(calendar.getTime());
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 获取某天前一天时间
     *
     * @param date
     * @return
     */
    public static String getPreDay(Date date) {
        return getPreDay(date, YYYY_MM_DD);
    }

    public static String getPreDay(Date date, String pattern) {
        return getPreDay(date, pattern, 1);
    }

    /**
     * 获取某天前一天的开始时间
     *
     * @param date
     * @return
     */
    public static String getPreStartTime(Date date) {
        return getPreStartTime(date, YYYY_MM_DD);
    }

    public static String getPreStartTime(Date date, String pattern) {
        return getPreStartTime(date, 1, pattern);
    }

    /**
     * 获取某天前几天的开始时间
     *
     * @param date
     * @param preDays
     * @return
     */
    public static String getPreStartTime(Date date, Integer preDays, String pattern) {
        return getNowStartTime(DatetimeUtil.changeToDate(getPreDay(date, pattern, preDays), pattern));
    }

    /**
     * 获取某天前一天的结束时间
     *
     * @param date
     * @return
     */
    public static String getPreEndTime(Date date) {
        return getPreEndTime(date, YYYY_MM_DD);
    }

    public static String getPreEndTime(Date date, String pattern) {
        return getPreEndTime(date, 1, pattern);
    }

    /**
     * 获取某天前几天的结束时间
     *
     * @param date
     * @param preDays
     * @return
     */
    public static String getPreEndTime(Date date, Integer preDays, String pattern) {
        return getNowEndTime(DatetimeUtil.changeToDate(getPreDay(date, pattern, preDays), pattern));
    }

    public static String getPreDay(Date date, String pattern, Integer preDays) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(sdf.parse(formatDate(date, Optional.ofNullable(pattern).orElse(YYYY_MM_DD))));
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - preDays);
            return formatDate(calendar.getTime(), pattern);
        } catch (Exception e) {
            return "";
        }
    }
    /** ********************************************************************************************** */
    /**
     * Description: 将java.util.Date对象转换为java.sql.Date对象
     *
     * @param _date 待转化的java.util.Date 对象
     * @return java.sql.Date对象
     */
    public static java.sql.Date changeToDBDate(Date _date) {
        if (_date == null) {
            return null;
        }

        return new java.sql.Date(_date.getTime());
    }

    /**
     * Description: 将字符串转换为java.sql.Date对象
     *
     * @param _date 待转化的字符串
     * @return java.sql.Date对象
     */
    public static java.sql.Date changeToDBDate(String _date) {
        return changeToDBDate(changeToDate(_date));
    }

    /**
     * Description: 将字符串转换为java.sql.Time对象
     *
     * @param _date 待转化的字符串
     * @return java.sql.Date对象
     */
    public static java.sql.Time changeToDBTime(String _date) {
        java.sql.Date sdate = changeToDBDate(changeToDate(_date));

        return new java.sql.Time(sdate.getTime());
    }

    /**
     * Description: 将字符串转换为java.sql.Timestamp对象
     *
     * @param _date 待转化的字符串
     * @return java.sql.Date对象
     */
    public static Timestamp changeToDBTimestamp(String _date) {
        java.sql.Date sdate = changeToDBDate(changeToDate(_date));

        return new Timestamp(sdate.getTime());
    }

    /**
     * Description: 将java.sql.Timestamp对象转换为java.util.Date对象
     *
     * @param _date 待转化的java.sql.Timestamp 对象
     * @return java.util.Date 对象
     */
    public static Date changeToDate(Timestamp _date) {
        return (Date) _date;
    }

    /**
     * 将java.util.Date对象转换为java.sql.Timestamp对象
     *
     * @param _date 待转化的java.util.Date 对象
     * @return java.sql.Timestamp对象
     */
    public static Timestamp changeToTimestamp(Date _date) {
        if (_date == null) {
            return null;
        }
        return new Timestamp(_date.getTime());
    }

    /**
     * 将java.sql.Date对象转换为java.util.Date对象
     *
     * @param _date 待转化的java.sql.Date对象
     * @return java.util.Date对象
     */
    public static Date changeToDate(java.sql.Date _date) {
        return (Date) _date;
    }

    public static Date changeToDate(Date _date, String _pattern) {
        return changeToDate(formatDate(_date, _pattern), _pattern);
    }

    /**
     * 使用中文字符以复杂的形式（"年 月 日 上午 时 分 秒"）格式化时间串
     *
     * @param _date 日期对象
     * @return 格式化后的日期
     */
    public static String complexFormatChineseDate(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        String timeStr = calendar.get(Calendar.YEAR) + "年"
                + (calendar.get(Calendar.MONTH) + 1) + "月"
                + calendar.get(Calendar.DAY_OF_MONTH) + "日";
        timeStr = timeStr + calendar.get(Calendar.HOUR_OF_DAY) + "时"
                + calendar.get(Calendar.MINUTE) + "分"
                + calendar.get(Calendar.SECOND) + "秒";
        calendar.clear();

        return timeStr;
    }

    /**
     * 使用格式 <b>_pattern </b>格式化日期输出
     *
     * @param _date    日期对象
     * @param _pattern 日期格式
     * @return 格式化后的日期
     */
    public static String formatDate(Date _date, String _pattern) {
        if (_date == null) {
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(_pattern);
        String stringDate = simpleDateFormat.format(_date);
        return stringDate;
    }

    public static String formatDate(Long time) {
        return formatDate(time, YYYY_MM_DD_HH_MM_SS_L_C);
    }

    public static String formatDate(Long time, String _pattern) {
        if (time == null) {
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(_pattern);
        String stringDate = simpleDateFormat.format(new Date(time));
        return stringDate;
    }

    /**
     * 使用格式 {@link #YYYY_MM_DD}格式化日期输出
     *
     * @param _date 日期对象
     * @return 格式化后的日期
     */
    public static String formatDate(Date _date) {
        return formatDate(_date, YYYY_MM_DD);
    }

    /**
     * 将时间串转变为时间对象，默认根据传入的字符串转化，如果字符串为空，则直接返回null
     *
     * @param _dateStr 时间串
     * @return 时间对象
     */
    public static Date changeToDate(String _dateStr) {
        if (StringUtils.isEmpty(_dateStr)) {
            return null;
        }
        return changeToDate(_dateStr, PATTERN_MAP.get(_dateStr.length()));
    }

    /**
     * Description:将时间串转变为时间对象
     *
     * @param _dateStr 时间串
     * @param _pattern 时间串使用的模式
     * @return 时间对象
     */
    public static Date changeToDate(String _dateStr, String _pattern) {
        Date date = null;

        if (StringUtils.isEmpty(_dateStr)) {
            return null;
        }

        SimpleDateFormat format = new SimpleDateFormat(_pattern);

        try {
            date = format.parse(_dateStr);
        } catch (ParseException pe) {
            throw new IllegalArgumentException("不能使用模式:[" + _pattern
                    + "]格式化时间串:[" + _dateStr + "]");
        }

        return date;
    }

    /**
     * 获得以参数_fromDate为基数的年龄
     *
     * @param _birthday 生日
     * @param _fromDate 起算时间
     * @return 年龄（起算年－出生年）
     */
    public static int getAgeFromBirthday(Date _birthday,
                                         Date _fromDate) {

        if (_fromDate == null) {
            _fromDate = new Date(System.currentTimeMillis());
        }
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_birthday);

        int birthdayYear = calendar.get(Calendar.YEAR);
        int birthdayMonth = calendar.get(Calendar.MONTH);
        int birthdayDay = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.clear();
        calendar.setTime(_fromDate);

        int currentYear = calendar.get(Calendar.YEAR);
        int currentMonth = calendar.get(Calendar.MONTH);
        int currentDay = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.clear();

        int age = currentYear - birthdayYear;

        if (!((currentMonth >= birthdayMonth) && (currentDay >= birthdayDay))) {
            age--;
        }

        return age;
    }

    /**
     * 获得当前年龄
     *
     * @param _birthday 生日
     * @return 年龄（起算年－出生年）
     */
    public static int getAgeFromBirthday(Date _birthday) {
        return getAgeFromBirthday(_birthday, new Date(System
                .currentTimeMillis()));
    }

    /**
     * 获得当前年龄
     *
     * @param _birthday 生日
     * @return 年龄（起算年－出生年）
     */
    public static int getAgeFromBirthday(Timestamp _birthday) {
        return getAgeFromBirthday(new Date(_birthday.getTime()),
                new Date(System.currentTimeMillis()));
    }

    /**
     * 获得系统时间的当前月的最后一天，包括年月日
     *
     * @return 返回值格式为：20030131
     */
    public static String getCurMonthFirstDay() {
        return getCurMonthFirstDay(new Date(System
                .currentTimeMillis()));
    }

    /**
     * 获得日期的当前月的最后一天，包括年月日
     *
     * @param date 参考时间
     * @return 返回值格式为：20030131
     */
    public static String getCurMonthFirstDay(Date date) {
        return formatDate(date, YYYY_MM) + "01";
    }

    /**
     * 获得系统时间当前月的最后一天，包括年月日
     *
     * @return 返回值格式为：20030131
     */
    public static String getCurMonthLastDay() {
        return getCurMonthLastDay(new Date(System.currentTimeMillis()));
    }

    /**
     * 获得日期的当前月的最后一天，包括年月日
     *
     * @param date 参考时间
     * @return 返回值格式为：20030131
     */
    public static String getCurMonthLastDay(Date date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(date);

        Date currentMonthFirstDayDate = changeToDate(formatDate(
                calendar.getTime(), YYYY_MM)
                + "01", YYYY_MM_DD);
        calendar.clear();
        calendar.setTime(currentMonthFirstDayDate);
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_YEAR, -1);

        return formatDate(calendar.getTime(), YYYY_MM_DD);
    }

    /**
     * 获得日期的天，以月为基
     *
     * @param _date 日期对象
     * @return 日期的天
     */
    public static int getDay(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        int day = calendar.get(Calendar.DAY_OF_MONTH);
        calendar.clear();

        return day;
    }

    /**
     * 获得两个Date之间的天数
     *
     * @param _startDate 开始时间
     * @param _endDate   结束时间
     * @return 两个Date间的天数
     */
    public static int getDayAmount(java.sql.Date _startDate,
                                   java.sql.Date _endDate) {
        int nDayAmount = 0;
        Calendar cldStart = Calendar.getInstance();
        Calendar cldEnd = Calendar.getInstance();

        cldStart.setTime(_startDate);
        cldEnd.setTime(_endDate);

        int nStart = cldStart.get(Calendar.DAY_OF_YEAR);
        int nEnd = cldEnd.get(Calendar.DAY_OF_YEAR);

        if ((nEnd - nStart) > 0) {
            nDayAmount = nEnd - nStart;
        } else {
            nDayAmount = 365 - (nEnd - nStart);
        }

        return nDayAmount;
    }

    /**
     * 计算两个日期间相隔的天数
     *
     * @param _startDate 起始日期
     * @param _endDate   终止日期
     * @return 相隔天数, 如果结果为正表示 <b>_endDate </b>在 <b>_startDate </b>之后；如果结果为负表示
     * <b>_endDate </b>在 <b>_startDate </b>之前；如果结果为0表示 <b>_endDate </b>和
     * <b>_startDate </b>是同一天。
     */
    public static int getDayCount(Date _startDate,
                                  Date _endDate) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_startDate);

        int startDay = calendar.get(Calendar.DAY_OF_YEAR);
        int startYear = calendar.get(Calendar.YEAR);
        calendar.clear();
        calendar.setTime(_endDate);

        int endDay = calendar.get(Calendar.DAY_OF_YEAR);
        int endYear = calendar.get(Calendar.YEAR);
        calendar.clear();

        return ((endYear - startYear) * 365) + (endDay - startDay);
    }

    /**
     * 获得日期的小时
     *
     * @param _date 日期对象
     * @return 日期的小时
     */
    public static int getHours(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        int value = calendar.get(Calendar.HOUR);
        calendar.clear();

        return value;
    }

    /**
     * 获得系统时间的上个月的第一天，包括年月日
     *
     * @return 返回值格式为：20030101
     */
    public static String getLastMonthFirstDay() {
        return getLastMonthFirstDay(new Date(System
                .currentTimeMillis()));
    }

    /**
     * 获得上个月的第一天，包括年月日
     *
     * @param date 参考时间
     * @return 返回值格式为：20030101
     */
    public static String getLastMonthFirstDay(Date date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);

        return formatDate(calendar.getTime(), YYYY_MM) + "01";
    }

    /**
     * 获得系统时间的上个月的最后一天，包括年月日
     *
     * @return 返回值格式为：20030131
     */
    public static String getLastMonthLastDay() {
        return getLastMonthLastDay(new Date(System
                .currentTimeMillis()));
    }

    /**
     * 获得日期的上个月的最后一天，包括年月日
     *
     * @param date 参考时间
     * @return 返回值格式为：20030131
     */
    public static String getLastMonthLastDay(Date date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(date);

        Date currentMonthFirstDayDate = changeToDate(formatDate(
                calendar.getTime(), YYYY_MM)
                + "01", YYYY_MM_DD);
        calendar.clear();
        calendar.setTime(currentMonthFirstDayDate);
        calendar.add(Calendar.DAY_OF_YEAR, -1);

        return formatDate(calendar.getTime(), YYYY_MM_DD);
    }

    /**
     * 获得日期的分钟
     *
     * @param _date 日期对象
     * @return 日期的分钟
     */
    public static int getMinutes(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        int value = calendar.get(Calendar.MINUTE);
        calendar.clear();

        return value;
    }

    /**
     * 获得日期的月
     *
     * @param _date 日期对象
     * @return 日期的月
     */
    public static int getMonth(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        // 以0开始
        int month = calendar.get(Calendar.MONTH);
        calendar.clear();

        return (month + 1);
    }

    /**
     * 获得两个Date间的月数, 天数超过14天算1个月
     *
     * @param _startDate 开始时间
     * @param _endDate   结束时间
     * @return 两个Date间的月数
     */
    public static int getMonthAmount(java.sql.Date _startDate,
                                     java.sql.Date _endDate) {
        int nYear = 0;
        int nMonth = 0;
        int nDay = 0;
        int nMonthAmount = 0;
        Calendar cldStart = Calendar.getInstance();
        Calendar cldEnd = Calendar.getInstance();

        cldStart.setTime(_startDate);
        cldEnd.setTime(_endDate);

        nYear = cldEnd.get(Calendar.YEAR) - cldStart.get(Calendar.YEAR);
        nMonth = cldEnd.get(Calendar.MONTH) - cldStart.get(Calendar.MONTH);
        nDay = cldEnd.get(Calendar.DATE) - cldStart.get(Calendar.DATE);

        if (nDay > 14) {
            nMonthAmount = (nYear * 12) + nMonth + 1;
        } else {
            nMonthAmount = (nYear * 12) + nMonth;
        }

        return nMonthAmount;
    }

    /**
     * 计算两个日期间相隔的月数, 每隔一月，其相隔天数必>30
     *
     * @param _startDate 起始日期
     * @param _endDate   终止日期
     * @return 相隔月数, 如果结果为正表示 <b>_endDate </b>在 <b>_startDate </b>之后；如果结果为负表示
     * <b>_endDate </b>在 <b>_startDate </b>之前；如果结果为0表示 <b>_endDate </b>和
     * <b>_startDate </b>是同一天。
     */
    public static int getMonthCount(Date _startDate,
                                    Date _endDate) {
        Date startDate = _startDate;
        Date endDate = _endDate;
        boolean afterFlag = false;

        if (_startDate.after(_endDate)) {
            startDate = _endDate;
            endDate = _startDate;
            afterFlag = true;
        }

        Calendar calendar = getCalendarInstance();
        calendar.setTime(startDate);

        int startDay = calendar.get(Calendar.DAY_OF_MONTH);
        int startMonth = calendar.get(Calendar.MONTH);
        int startYear = calendar.get(Calendar.YEAR);
        int countDayOfStartMonth = calendar
                .getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.clear();
        calendar.setTime(endDate);

        int endDay = calendar.get(Calendar.DAY_OF_MONTH);
        int endMonth = calendar.get(Calendar.MONTH);
        int endYear = calendar.get(Calendar.YEAR);
        calendar.clear();

        int result = ((endYear - startYear) * 12)
                + (endMonth - (startMonth + 1))
                + (int) ((endDay + (countDayOfStartMonth - startDay)) / countDayOfStartMonth);

        if (afterFlag) {
            return -result;
        } else {
            return result;
        }
    }

    /**
     * 获得日期的小秒
     *
     * @param _date 日期对象
     * @return 日期的秒
     */
    public static int getSeconds(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        int value = calendar.get(Calendar.SECOND);
        calendar.clear();

        return value;
    }

    /**
     * 获得日期的年
     *
     * @param _date 日期对象
     * @return 日期的年
     */
    public static int getYear(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        int year = calendar.get(Calendar.YEAR);
        calendar.clear();

        return year;
    }

    /**
     * 使用中文字符以简单的形式（"年 月 日"）格式化时间串
     *
     * @param _date 日期对象
     * @return 格式化后的日期
     */
    public static String simpleFormatChineseDate(Date _date) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_date);

        String timeStr = calendar.get(Calendar.YEAR) + "年"
                + (calendar.get(Calendar.MONTH) + 1) + "月"
                + calendar.get(Calendar.DAY_OF_MONTH) + "日";
        calendar.clear();

        return timeStr;
    }

    /**
     * <p>
     * Title :雅普兰Web开发框架
     * </p>
     * <p>
     * Description: 得到当前时间（Timestamp）
     * </p>
     */
    public static Timestamp getCurTime() {
        Timestamp sdate = new Timestamp(System
                .currentTimeMillis());

        return sdate;
    }

    /**
     * Description: 在_dt的基础上加上_day天
     *
     * @param _dt  日期
     * @param _day 天数
     * @return
     */
    public static Date getDateByDay(java.sql.Date _dt, int _day) {
        Calendar calendar = getCalendarInstance();
        calendar.setTime(_dt);
        calendar.add(Calendar.DAY_OF_MONTH, _day);

        return calendar.getTime();
    }

    /**
     * 取期末日期
     *
     * @param _dt
     * @param _period <ul>
     *                <li>M 月末
     *                <li>Q 季末
     *                <li>Y 年末
     *                <li>H 半年末
     *                <li>m 上月末
     *                <li>q 上季末
     *                <li>y 上年末
     *                <li>h 上半年末
     *                </ul>
     * @return
     */
    public static Date getPeriodEnd(Date _dt, char _period) {
        Calendar cal = getCalendarInstance();
        cal.setTime(_dt);
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int month = cal.get(Calendar.MONTH);//1月=0,12月=11
        int week = cal.get(Calendar.DAY_OF_WEEK);
        switch (_period) {
            case 'M':
                cal.add(Calendar.MONTH, 1);//to next month
                day = cal.get(Calendar.DAY_OF_MONTH);
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            case 'Q':
                cal.add(Calendar.MONTH, 3 - month % 3);//to next quarter
                // first month
                day = cal.get(Calendar.DAY_OF_MONTH);
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            case 'Y':
                cal.add(Calendar.MONTH, 12 - month);//to next year first month
                day = cal.get(Calendar.DAY_OF_MONTH);
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            case 'H':
                cal.add(Calendar.MONTH, 6 - (month) % 6);//to next halfyear
                // first month
                day = cal.get(Calendar.DAY_OF_MONTH);
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            case 'm':
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            case 'q':
                cal.add(Calendar.MONTH, 0 - (month) % 3);//to this quarter
                // first month
                day = cal.get(Calendar.DAY_OF_MONTH);
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            case 'y':
                cal.add(Calendar.MONTH, 0 - month);//to this year first month
                day = cal.get(Calendar.DAY_OF_MONTH);
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            case 'h':
                cal.add(Calendar.MONTH, 0 - (month) % 6);//to this halfyear
                // first month
                day = cal.get(Calendar.DAY_OF_MONTH);
                cal.add(Calendar.DAY_OF_MONTH, 0 - day);//to last month end
                break;
            default:
                break;
        }
        return cal.getTime();
    }

    /**
     * 获取指定类型日期
     *
     * @param date   日期(字符型YYYYMMDD格式)
     * @param period 期间类型
     *               ''D'' 日 ''M'' 月 ''Q'' 季 ''H' 半年 ''Y'' 年 “MB”月初 “ME”月末 “QB”季初 “QE”季末“HB”半年初 “HE”半年末 “YB”年初 “YE”年末
     * @param offset 负数为前，正数为后
     * @return 指定类型日期
     */
    public static String getSpeldate(String date, String period, int offset) {
        Date dt = changeToDate(date);
        Calendar cal = getCalendarInstance();
        cal.setTime(dt);
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int month = cal.get(Calendar.MONTH);//1月=0,12月=11
        String upperiod = period.toUpperCase();
        //if("MB".equals(upperiod)){
        if ("MB".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.DAY_OF_MONTH, 1 - day);
        } else if ("ME".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.MONTH, 1);//to next month
            day = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 0 - day);
        } else if ("QB".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.MONTH, 0 - month % 3);
            day = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 1 - day);
        } else if ("QE".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.MONTH, 3 - month % 3);
            day = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 0 - day);
        } else if ("HB".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.MONTH, 0 - (month) % 6);
            day = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 1 - day);
        } else if ("HE".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.MONTH, 6 - (month) % 6);
            day = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 0 - day);
        } else if ("YB".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.MONTH, 0 - month);
            day = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 1 - day);
        } else if ("YE".equalsIgnoreCase(upperiod)) {
            cal.add(Calendar.MONTH, 12 - month);
            day = cal.get(Calendar.DAY_OF_MONTH);
            cal.add(Calendar.DAY_OF_MONTH, 0 - day);
        }
        //非当期
        if (offset != 0) {
            if ("M".equalsIgnoreCase(upperiod) || "MB".equalsIgnoreCase(upperiod) || "ME".equalsIgnoreCase(upperiod)) {
                cal.add(Calendar.MONTH, offset);
            } else if ("Q".equalsIgnoreCase(upperiod) || "QB".equalsIgnoreCase(upperiod) || "QE".equalsIgnoreCase(upperiod)) {
                cal.add(Calendar.MONTH, offset * 3);
            } else if ("H".equalsIgnoreCase(upperiod) || "HB".equalsIgnoreCase(upperiod) || "HE".equalsIgnoreCase(upperiod)) {
                cal.add(Calendar.MONTH, offset * 6);
            } else if ("Y".equalsIgnoreCase(upperiod) || "YB".equalsIgnoreCase(upperiod) || "YE".equalsIgnoreCase(upperiod)) {
                cal.add(Calendar.MONTH, offset * 12);
            }
        }
        return formatDate(cal.getTime(), YYYY_MM_DD);
    }

    /**
     * Description: 根据Timestamp得到Time
     *
     * @param _timesmp
     * @return
     */
    public static java.sql.Time getTimeByTimestamp(Timestamp _timesmp) {
        Calendar cal = getCalendarInstance();
        cal.setTimeInMillis(_timesmp.getTime());
        String str = String.valueOf(cal.get(Calendar.HOUR_OF_DAY)) + ":"
                + String.valueOf(cal.get(Calendar.MINUTE)) + ":"
                + String.valueOf(cal.get(Calendar.SECOND));

        return java.sql.Time.valueOf(str);
    }

    /**
     * Description: 得到当前时间的前/后@offset天的时间
     *
     * @param offset    负数为前，正数为后
     * @param splitdate 日期分割符
     * @param splittime 时间分割符
     * @return
     */
    public static String getPriorDay(int offset, String splitdate,
                                     String splittime) {

        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        Calendar theday = Calendar.getInstance();
        theday.add(Calendar.DATE, offset);

        df.applyPattern("yyyy" + splitdate + "MM" + splitdate + "dd" + " "
                + "HH" + splittime + "mm" + splittime + "ss");
        return df.format(theday.getTime());
    }

    public static Calendar getCalendarInstance() {
        Calendar cal = Calendar.getInstance(TimeZone.getDefault(),
                Locale.SIMPLIFIED_CHINESE);
        return cal;

    }

    /**
     * 按精度比较日期. <br>
     *
     * @param date1
     * @param date2
     * @param precision 精度=整数： <br>
     *                  Calendar.YEAR <br>
     *                  Calendar.MONTH <br>
     *                  Calendar.DAY_OF_MONTH <br>
     *                  Calendar.MINUTE <br>
     *                  Calendar.SECOND <br>
     *                  Calendar.MILLISECOND
     * @return the value 0 if the argument Date is equal to this Date; a value
     * less than 0 if this Date is before the Date argument; and a value
     * greater than 0 if this Date is after the Date argument
     */
    public static int compareDate(final Date date1, final Date date2,
                                  int precision) {
        Calendar c = Calendar.getInstance();

        List fields = new ArrayList();
        fields.add(new Integer(Calendar.YEAR));
        fields.add(new Integer(Calendar.MONTH));
        fields.add(new Integer(Calendar.DAY_OF_MONTH));
        fields.add(new Integer(Calendar.MINUTE));
        fields.add(new Integer(Calendar.SECOND));
        fields.add(new Integer(Calendar.MILLISECOND));

        Date d1 = date1;
        Date d2 = date2;
        if (fields.contains(new Integer(precision))) {
            c.setTime(date1);
            for (int i = 0; i < fields.size(); i++) {
                int field = ((Integer) fields.get(i)).intValue();
                if (field > precision) {
                    c.set(field, 0);
                }
            }
            d1 = c.getTime();
            c.setTime(date2);
            for (int i = 0; i < fields.size(); i++) {
                int field = ((Integer) fields.get(i)).intValue();
                if (field > precision) {
                    c.set(field, 0);
                }
            }
            d2 = c.getTime();
        }
        return d1.compareTo(d2);
    }

    public static int compareDate(Date date, Date date1, String pattern) {
        date = changeToDate(formatDate(date, pattern), pattern);
        date1 = changeToDate(formatDate(date1, pattern), pattern);
        return date.compareTo(date1);
    }

    public static Calendar convertTimeZone(Calendar cal, String zone) {
        Calendar ret = Calendar.getInstance();
        TimeZone toZone = TimeZone.getTimeZone(zone);
        long curmillis = cal.getTimeInMillis();
        ret.setTimeInMillis(curmillis + toZone.getRawOffset()
                - cal.getTimeZone().getRawOffset());

        return ret;
    }

    /**
     * 日期字符串，返回一个Calendar的日期对象
     *
     * @param datetime 日期字符串
     * @param pattern  格式（yyyy-MM-dd 、yyyyMMdd）
     * @return
     * @throws Exception
     */
    private static Calendar getDateCalendar(String datetime, String pattern)
            throws Exception {
        try {
            SimpleDateFormat df = new SimpleDateFormat(pattern);
            Date date = df.parse(datetime);
            Calendar cd = Calendar.getInstance();
            cd.setTime(date);
            return cd;
        } catch (ParseException pe) {
            throw new Exception(datetime + "格式不对，必须是yyyy-MM-dd 、 yyyyMMdd 格式");
        } catch (Exception ex) {

            throw ex;
        }
    }

    /**
     * 默认时间字符串格式为yyyyMMdd
     *
     * @param datetime
     * @return
     * @throws Exception
     */
    private static Calendar getDateCalendar(String datetime) throws Exception {
        return getDateCalendar(datetime, "yyyyMMdd");
    }

    /**
     * 获取当前日期的上一天
     *
     * @param dateOfChar 字符串格式
     * @return
     * @throws Exception
     */
    public static String getPrirDay(String dateOfChar) throws Exception {
        Calendar calendar = getDateCalendar(dateOfChar);
        calendar.add(Calendar.DATE, -1);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }

    /**
     * 获取当前日期的下一天
     * 默认 yyyyMMdd
     *
     * @param dateOfChar 字符串格式
     * @return
     * @throws Exception
     */
    public static String getNextDay(String dateOfChar) {
        return getNextDay(dateOfChar, YYYY_MM_DD);
    }

    public static String getNextDay(String dateOfChar, String pattern) {
        return getNextDay(dateOfChar, 1, pattern);
    }

    public static String getNextStartDay(Date date) {
        return getNextStartDay(date, YYYY_MM_DD);
    }

    public static String getNextStartDay(Date date, String pattern) {
        return getNextStartDay(date, 1, pattern);
    }

    public static String getNextStartDay(Date date, Integer nextDays, String pattern) {
        return DatetimeUtil.getNowStartTime(DatetimeUtil.changeToDate(DatetimeUtil.getNextDay(formatDate(date, pattern), nextDays, pattern), pattern));
    }

    public static String getNextDay(String dateOfChar, Integer nextDays, String pattern) {
        try {
            Calendar calendar = getDateCalendar(dateOfChar);
            calendar.add(Calendar.DATE, nextDays);
            return formatDate(calendar.getTime(), pattern);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getNowNextStartDay() {
        return getNowNextStartDay(YYYY_MM_DD);
    }

    public static String getNowNextStartDay(String pattern) {
        return getNextStartDay(new Date(), pattern);
    }

    public static String getNextEndDay(Date date) {
        return getNextEndDay(date, YYYY_MM_DD);
    }

    public static String getNextEndDay(Date date, String pattern) {
        return getNextEndDay(date, 1, pattern);
    }

    public static String getNextEndDay(Date date, Integer nextDays, String pattern) {
        return DatetimeUtil.getNowEndTime(DatetimeUtil.changeToDate(DatetimeUtil.getNextDay(formatDate(date, pattern), nextDays, pattern), pattern));
    }

    public static String getNowNextEndDay() {
        return getNowNextEndDay(YYYY_MM_DD);
    }

    public static String getNowNextEndDay(String pattern) {
        return getNextEndDay(new Date(), pattern);
    }

    /**
     * 获取当前日期的下一年
     *
     * @param dateOfChar 字符串格式
     * @return
     * @throws Exception
     */
    public static String getNextYear(String dateOfChar) throws Exception {
        Calendar calendar = getDateCalendar(dateOfChar);
        /**
         * 得到明年
         */
        calendar.add(Calendar.YEAR, 1);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }

    /**
     * 获取当前日期的前一年
     *
     * @param dateOfChar 字符串格式
     * @return
     * @throws Exception
     */
    public static String getLastYear(String dateOfChar) throws Exception {
        /**
         * 得到去年
         */
        Calendar calendar = getDateCalendar(dateOfChar);
        calendar.add(Calendar.YEAR, -1);
        return new SimpleDateFormat("yyyyMMdd").format(calendar.getTime());
    }

    /**
     * 是否当天是期末
     *
     * @param datestr 需检查的日期
     * @param format  可为空 默认日期格式:yyyyMMdd
     * @param edtype  月末M 年末Y
     * @return
     */
    public static boolean isEndOfDay(String datestr, String format, String edtype) throws Exception {
        boolean result = false;
        ArrayList<String> formatlist = new ArrayList<>();
        formatlist.add(YYYY_MM_DD_L);
        formatlist.add(YYYY_MM_DD);

        //检查日期格式是否合法
        if ("".equals(format) || format == null) {
            format = YYYY_MM_DD;
        } else if (!formatlist.contains(format)) {
            return false;
        }

        //是否月末
        if ("M".equals(edtype)) {
            try {
                String nextdate_month = getNextDay(datestr).substring(4, 6);
                String todate_month = datestr.substring(4, 6);
                if (!todate_month.equals(nextdate_month)) {
                    result = true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            //是否年末
            if ("1231".equals(getNow(format).substring(4, 8))) {
                result = true;
            }
        }
        return result;
    }

    /**
     * 根据指定日期格式，将字符串类型转换成日期类型
     *
     * @param str
     * @param format
     * @return
     */
    public static Date convertStrToDate(String str, String format) {
        Date date = null;
        if (str == null || "".equals(str.trim()) || "null".equalsIgnoreCase(str)) {
            return date;
        }
        SimpleDateFormat df = new SimpleDateFormat(format);
        try {
            date = df.parse(str);
        } catch (ParseException pe) {
            throw new IllegalArgumentException("不能使用模式:[" + format + "]格式化时间串:[" + str + "]");
        }
        return date;
    }


    public static Long getDateBeginAndEnd(Date date, String str) {
        String strDate = getYear(date) + "-" + getMonth(date) + "-" + getDay(date) + " " + str;
        date = changeToDate(strDate, DatetimeUtil.YYYY_MM_DD_HH_MM_SS_L_C);
        return date.getTime();
    }

    /**
     * 获取2个时间之间的天数的毫秒数,默认取值为秒
     *
     * @param begin
     * @param end
     * @return
     */
    public static List<Map<String, Date>> getBetweenDates(Date begin, Date end) {
        List<Map<String, Date>> list = new ArrayList<>();
        //判断开始时间和结束时间是否是一天
        if (DatetimeUtil.compareDate(begin, end, DatetimeUtil.YYYY_MM_DD) == 0) {
            Map<String, Date> map = Maps.newHashMap();
            map.put("begin", begin);
            map.put("end", end);
            list.add(map);
        } else {
            Map<String, Date> beginMap = Maps.newHashMap();
            beginMap.put("begin", begin);
            Long beginEnd = getDateBeginAndEnd(begin, "23:59:59");
            beginMap.put("end", new Date(beginEnd));
            list.add(beginMap);
            Long endBegin = getDateBeginAndEnd(end, "00:00:00");
            for (Long i = beginEnd + 1000; i < endBegin; ) {
                Map<String, Date> map = Maps.newHashMap();
                Long j = i + 1000 * 60 * 60 * 24;
                map.put("begin", new Date(i));
                map.put("end", new Date(j - 1000));
                list.add(map);
                i = j;
            }
            Map<String, Date> endMap = Maps.newHashMap();
            endMap.put("begin", new Date(endBegin));
            endMap.put("end", end);
            list.add(endMap);
        }
        return list;
    }

    /**
     * Long的秒数 (除去年月日)
     *
     * @param time
     * @return 小时
     */
    public static String getHour(Long time) {
        /**
         * 毫秒变秒
         */
        time = time / 1000;
        /**
         * 每3600秒是一小时
         */
        time = time / 3600;
        if (time < 10) {
            return "0" + time;
        }
        return time + "";
    }

    /**
     * 01:02:03
     *
     * @param time
     * @return
     */
    public static String getHourAndMinAndSec(Long time) {
        return getHour(time) + ":" + getMin(time) + ":" + getSec(time);
    }

    /**
     * 2.1小时
     *
     * @param time
     * @return
     */
    public static String getHourAndMinInfo(Long time) {
        return Double.valueOf(getHour(time)) + Double.valueOf(getMin(time)) / 60 + "";
    }

    public static int getDateHour(Date date) {
        return getCalendar(date).get(Calendar.HOUR_OF_DAY);
    }

    public static Calendar getCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    public static int getDateHour(Long time) {
        return getDateHour(new Date(time));
    }

    /**
     * Long的秒数 (除去年月日)
     *
     * @param time
     * @return 分钟
     */
    public static String getMin(Long time) {
        /**
         *毫秒变秒
         */
        time = time / 1000;
        /**
         * 除余小时在除以60秒则为分钟
         */
        time = time % 3600 / 60;
        if (time < 10) {
            return "0" + time;
        }
        return time + "";
    }

    /**
     * Long的秒数 (除去年月日)
     *
     * @param time
     * @return 秒数
     */
    public static String getSec(Long time) {
        /**
         * 毫秒变秒
         */
        time = time / 1000;
        /**
         * 获取秒数
         */
        time = time % 3600 % 60;
        if (time < 10) {
            return "0" + time;
        }
        return time + "";
    }

    public static String getHourAndMin(Long time) {
        int hour = Integer.parseInt(DatetimeUtil.getHour(time));
        int min = Integer.parseInt(DatetimeUtil.getMin(time));
        StringBuffer sb = new StringBuffer();
        if (hour > 0) {
            sb.append(hour + "小时");
        }
        if (min > 0) {
            sb.append(min + "分钟");
        }
        return sb.toString();
    }

    /**
     * 是否时间字符串
     *
     * @param _dateStr
     * @return
     */
    public static Boolean isDateString(String _dateStr) {
        try {
            changeToDate(_dateStr, PATTERN_MAP.get(_dateStr.length()));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 字符串是否时间
     *
     * @param _dateStr
     * @param _pattern
     * @return
     */
    public static Date isChangeDate(String _dateStr, String _pattern) {
        try {
            return changeToDate(_dateStr, _pattern);
        } catch (Exception e) {
            return null;
        }
    }

    public static Date getEndHourByDate(Date date) {
        return changeToDate(formatDate(date, YYYY_MM_DD_HH_L) + ":59:59", YYYY_MM_DD_HH_MM_SS_L_C);
    }

    /**
     * 获取传入时间的间隔小时，负数表示几小时前，正数几小时后
     *
     * @param date
     * @param hour
     * @return
     */
    public static Date getUpdateHour(Date date, int hour) {
        return getUpdateDate(date, Calendar.HOUR, hour);
    }

    public static Date getUpdateHour(int hour) {
        return getUpdateDate(new Date(), Calendar.HOUR, hour);
    }

    /**
     * 获取传入时间的间隔分钟，负数表示几分钟前，正数几分钟后
     *
     * @param date
     * @param minute
     * @return
     */
    public static Date getUpdateMinute(Date date, int minute) {
        return getUpdateDate(date, Calendar.MINUTE, minute);
    }

    public static Date getUpdateMinute(int minute) {
        return getUpdateDate(new Date(), Calendar.MINUTE, minute);
    }

    /**
     * 获取传入时间的间隔小时，负数表示几天前，正数几天后
     *
     * @param date
     * @param day
     * @return
     */
    public static Date getUpdateDay(Date date, int day) {
        return getUpdateDate(date, Calendar.DAY_OF_MONTH, day);
    }

    public static Date getUpdateDay(int day) {
        return getUpdateDate(new Date(), Calendar.DAY_OF_MONTH, day);
    }

    /**
     * 获取传入时间的间隔天数，负数表示几小时前，正数几小时后
     *
     * @param date
     * @param calendarTime
     * @return
     */
    public static Date getUpdateDate(Date date, int calendarTime, int time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(calendarTime, calendar.get(calendarTime) + time);
        return calendar.getTime();
    }

    /**
     * 获取当前时间之后的毫秒数，负数为获取当前时间之前的毫秒数
     *
     * @return
     */
    public static Date getNewDateBySeconde(Date date, int second) {
        return new Date(date.getTime() + second * 1000);
    }

    /**
     * 毫秒转时间01:02:03，超过24小时显示100:00:00类型
     *
     * @param time
     * @return
     */
    public static String getHourAndMinAndSecTime(Long time) {
        return getHour(time) + ":" + getMin(time) + ":" + getSec(time);
    }

    public static String getHourAndMinAndSecStr(Long time) {
        return getHour(time) + "小时" + getMin(time) + "分" + getSec(time) + "秒";
    }

    public static String getHourAndMinStr(Long time) {
        return getHour(time) + "小时" + getMin(time) + "分";
    }

    /**
     * 获取UNIX的最早时间
     *
     * @return
     */
    public static Date getUnixFirsteDate() {
        return new Date(0L);
    }

    /**
     * 获取2个时间之间每月的最后一天,默认最后一个月的结束时间为当前时间
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<Date> getBetweenMonthLastDay(Date startDate, Date endDate) {
        return getBetweenMonthLastDay(startDate, endDate, true);
    }

    /**
     * 获取2个时间之间每月的最后一天
     *
     * @param startDate
     * @param endDate
     * @param flag      是否加入最后的当前时间作为最后一个月的结束时间，true加入，false不加入
     * @return
     */
    public static List<Date> getBetweenMonthLastDay(Date startDate, Date endDate, Boolean flag) {
        int len = LocalDateUtil.getBetweenMonthLength(startDate, endDate, true);
        Date startTime = changeToDate(getCurMonthFirstDay(startDate), DatetimeUtil.YYYY_MM_DD);
        List<Date> list = new ArrayList<>(len);
        for (int i = 0; i < len; i++) {
            startTime = new Date(startTime.getTime() + (LocalDateUtil.getMonthDayLength(startTime) - 1) * 24 * 3600 * 1000L);
            if (startTime.compareTo(endDate) <= 0) {
                list.add(startTime);
            } else if (flag) {
                list.add(endDate);
            }
            startTime = new Date(startTime.getTime() + 24 * 3600 * 1000L);
        }
        return list;
    }

    /**
     * 获取2个时间之间每月的第一天,默认不把当前时间最为当月的第一天
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static List<Date> getBetweenMonthFirstDay(Date startDate, Date endDate) {
        return getBetweenMonthFirstDay(startDate, endDate, false);
    }

    /**
     * 获取2个时间之间每月的第一天
     *
     * @param startDate
     * @param endDate
     * @param flag      是否加入开始时间为当月的第一天，true加入，false不加入
     * @return
     */
    public static List<Date> getBetweenMonthFirstDay(Date startDate, Date endDate, Boolean flag) {
        int len = LocalDateUtil.getBetweenMonthLength(startDate, endDate, true);
        Date startTime = changeToDate(getCurMonthFirstDay(startDate), DatetimeUtil.YYYY_MM_DD);
        List<Date> list = new ArrayList<>(len);
        for (int i = 0; i < len; i++) {
            if (startTime.compareTo(startDate) >= 0) {
                list.add(startTime);
            } else if (flag) {
                list.add(startDate);
            }
            startTime = new Date(startTime.getTime() + LocalDateUtil.getMonthDayLength(startTime) * 24 * 3600 * 1000L);
        }
        return list;
    }

    /**
     * 获取2个月份时间中间每月有多少天数
     *
     * @param startDate 开始时间大于当月第一天，从当前时间算到月末
     * @param endDate   结束时间小于当月最后一天，从当月第一天算到当前时间
     * @return
     */
    public static List<Integer> getBetweenMonthDayLength(Date startDate, Date endDate) {
        int len = LocalDateUtil.getBetweenMonthLength(startDate, endDate, true);
        Date startTime = changeToDate(getCurMonthFirstDay(startDate), DatetimeUtil.YYYY_MM_DD);
        List<Integer> list = new ArrayList<>(len);
        list.add(LocalDateUtil.getMonthDayLength(startTime) - LocalDateUtil.getDayInMonth(startDate) + 1);
        for (int i = 1; i < len - 1; i++) {
            list.add(LocalDateUtil.getMonthDayLength(startTime));
            startTime = new Date(startTime.getTime() + LocalDateUtil.getMonthDayLength(startTime) * 24 * 3600 * 1000L);
        }
        list.add(LocalDateUtil.getDayInMonth(endDate));
        return list;
    }

    public static void main(String[] args) {
        System.out.println(getPreDay(new Date(), YYYY_MM_DD_L));
        System.out.println(changeToDate("2019-01-01 20:14:58").getTime());
    }
}
